/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package server.tools;

import server.beans.SessionBean;
import server.boundary.AccountFacade;
import server.boundary.TransactionFacade;
import server.boundary.TransactionTypeFacade;
import server.boundary.UserFacade;
import com.google.common.hash.Hashing;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import server.entities.User;
import types.AuthXML;
import types.ErrorXML;
import types.RequestXML;
import types.ResponseXML;

/**
 *
 * @author efim
 */
@Stateless 
public class XMLRequester {
    @EJB
    private SessionBean sessionBean;
    @EJB
    private UserFacade userFacade;
    @EJB
    private TransactionTypeFacade transactionTypeFacade;
    @EJB
    private TransactionFacade transactionFacade;
    @EJB
    private AccountFacade accountFacade;
    

    public XMLRequester() {
    }
    
    
    public ByteArrayOutputStream Request(InputStream is) throws IOException
    {       
        Object result = null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {            
            RequestXML data = (RequestXML) JAXBContext.newInstance(RequestXML.class).createUnmarshaller().unmarshal(is);
            Map<String, String> params = new HashMap<>();
            for (RequestXML.Params.Param p : data.getParams().getValues()) {
                params.put(p.getName(), p.getValue());
            }
            
            if ((params.get("access_token")==null)||(userFacade.getUserWithAccessToken(params.get("access_token"))==-1)) {
                result = new ErrorXML(102, "Недействительный ключ авторизации!");
            } else {
                switch (data.getMethod()) {
                    case "GetUsers":
                        result = new ResponseXML(userFacade.getUser(params));
                        break;
                    case "CreateUser":
                        result = new ResponseXML(userFacade.createUser(params));
                        break;
                    case "GetAccounts":
                        result = new ResponseXML(accountFacade.getAccounts(params));
                        break;
                    case "CreateAccount":
                        result = new ResponseXML(accountFacade.createAccount(params));
                        break;
                    case "CreateTransaction":
                        result = new ResponseXML(transactionFacade.createTransaction(params));
                        break;
                    case "GetTransactions":
                        result = new ResponseXML(transactionFacade.getTransactions(params));
                        break;
                    case "GetTransactionTypes":
                        result = new ResponseXML(transactionTypeFacade.getTransactionTypes(params));
                        break;
                    default:
                        result = new ErrorXML(100, "Не существующий метод");
                        break;
                }
            }
            JAXBContext.newInstance(result.getClass()).createMarshaller().marshal(result, os);
            JAXBContext.newInstance(result.getClass()).createMarshaller().marshal(result, System.out);
        } 
        catch (JAXBException ex) {
            Logger.getLogger(XMLRequester.class.getName()).log(Level.SEVERE, null, ex);
        } 
        
        return os;
    }
    
    public ByteArrayOutputStream getAccessToken(String email,String password)
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            Map<String, String> params = new HashMap<>();
            Date curr = new Date();
            Object result = null;
            String accessToken = Hashing.md5().hashLong(curr.getTime()).toString();
            params.put("email", email);
            params.put("password", password);
            params.put("access_token", accessToken);
            int rows = userFacade.loginUser(params);
            if (rows != 0) {
                sessionBean.setAccessToken(accessToken);
                long userId = userFacade.getUserWithAccessToken(accessToken);
                System.out.println("user_id"+userId);
                result = new ResponseXML<AuthXML>(new AuthXML(accessToken, userId));
            } else {
                result = new ErrorXML(101, "Неверная комбинация логина и пароля!");
            }
            JAXBContext.newInstance(result.getClass()).createMarshaller().marshal(result, os);
        } catch (JAXBException ex) {
            Logger.getLogger(XMLRequester.class.getName()).log(Level.SEVERE, null, ex);
        }
        return os;
    }
    
    public ByteArrayOutputStream registration(Map<String, String> params)
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            
            Object result = null;
            
            User user = userFacade.createUser(params);

            result = new ResponseXML<User>(user);

            JAXBContext.newInstance(result.getClass()).createMarshaller().marshal(result, os);
        } catch (JAXBException ex) {
            Logger.getLogger(XMLRequester.class.getName()).log(Level.SEVERE, null, ex);
        }
        return os;
    }
    
    
}
